package com.bj58.mis.apm.server.statistics.service;

import com.bj58.mis.apm.server.statistics.common.RequestContext;
import com.bj58.mis.apm.server.statistics.dto.common.Pair;
import com.bj58.mis.apm.server.statistics.dto.roc.AuthCube;
import com.bj58.mis.apm.server.statistics.mapper.RocAuthMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.List;
import java.util.stream.Collectors;

/**
 * @author: zhangfx
 * @create: 2018-06-25 18:41
 **/
public class BaseService<Mapper> {
    protected Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    protected Mapper mapper;

    @Autowired
    private RocAuthMapper rocAuthMapper;

    @Autowired
    protected RequestContext requestContext;

    /**
     * 查询cube的负责人列表，用于显示
     * @param cubeId
     * @return 负责人OA账号列表,逗号分割
     */
    protected String getCubeOwners(String cubeId){
        List<AuthCube> authCubes = rocAuthMapper.queryAuthCubeByCube(cubeId);
        StringBuilder owners = new StringBuilder();
        authCubes.forEach(authCube -> owners.append(",").append(authCube.getOwnerRealName()).append("("+authCube.getOwner()+")"));
        return owners.length()>0 ? owners.toString().substring(1) : null;
    }

    /**
     * 获取Roc创建对Cube总数量
     * @return
     */
    protected long getTotalRocCube(String projectId) {
        return rocAuthMapper.queryRocCubeCount(projectId);
    }

    /**
     * 判断用户是否为管理员
     * @param username OA系统账号
     * @return
     */
    public boolean isAdmin(String username) {
        return requestContext.getLoginUser().isAdmin();
    }

    public List<Pair> getAuthProjectIdList(String owner){
        return rocAuthMapper.getAuthProjectIdList(owner);
    }
    /**
     * 获取用户负责的Cube列表
     * @param owner  OA系统账号
     * @return
     */
    public List<String> getAuthCubeIdList(String owner) {
        return getAuthCubeIdList(owner, null);
    }

    /**
     * 获取用户在指定项目下负责的Cube列表
     * @param owner OA系统账号
     * @param projectId 项目ID，如果为空就获取用户负责的所以Cube列表，等同于getAuthCubeIdList(username)
     * @return
     */
    public List<String> getAuthCubeIdList(String owner, String projectId) {
        return rocAuthMapper.queryAuthCubeByOwnerAndProject(owner, projectId).stream().map(authCube -> authCube.getCubeId()).collect(Collectors.toList());
    }

    public List<Pair> getOwnersByRoc(String projectId, String keyword) {
        return rocAuthMapper.qeuryOwners(projectId, keyword);
    }

    /**
     * 检查用户的Cube权限
     * @param username OA系统账号
     * @param projectId 项目ID
     * @return 返回CubeAuth
     */
    protected CubeAuth checkCubeAuth(String username, String projectId){
        boolean isAdmin = username==null || this.isAdmin(username);
        List<String> authCubeIdList = null;
        boolean isNoAuth = false;
        if(!isAdmin){
            authCubeIdList = this.getAuthCubeIdList(username, projectId);
            isNoAuth = authCubeIdList==null || authCubeIdList.size()==0;
        }
        return new CubeAuth(isNoAuth, isAdmin, authCubeIdList);
    }


    public static class CubeAuth{
        private ThenAction thenAction;
        private NoAuthAction noAuthAction;

        private boolean isNoAuth;
        private boolean isAdmin;
        private List<String> authCubeIdList;

        CubeAuth(boolean isNoAuth, boolean isAdmin, List<String> authCubeIdList){
            this.isNoAuth = isNoAuth;
            this.isAdmin = isAdmin;
            this.authCubeIdList = authCubeIdList;
        }

        public CubeAuth then(ThenAction action){
            this.thenAction = action;
            return this;
        }
        public CubeAuth noAuth(NoAuthAction action){
            this.noAuthAction = action;
            return this;
        }
        @SuppressWarnings("unchecked")
        public <T> T done(){
            if(isNoAuth){
                return (T) noAuthAction.run();
            }else {
                return (T) thenAction.run(isAdmin, authCubeIdList);
            }
        }
    }

    @FunctionalInterface
    public interface ThenAction {
        Object run(boolean isAdmin, List<String> authCubeIdList);
    }

    @FunctionalInterface
    public interface NoAuthAction {
        Object run();
    }
}

